package com.lyf.boot.auth;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lyf.boot.base.system.dao.BaseSysUserDao;
import com.lyf.boot.base.system.entity.SysClient;
import com.lyf.boot.base.system.entity.SysUser;
import com.lyf.boot.constant.Constant;
import com.lyf.boot.core.model.LoginUser;
import com.lyf.boot.core.model.LoginVo;
import com.lyf.boot.core.service.IAuthStrategy;
import com.lyf.boot.modules.index.entity.LoginDto;
import com.lyf.boot.utils.AuthUtil;
import com.lyf.boot.utils.JsonUtil;
import com.lyf.boot.utils.ServerUtil;
import com.lyf.boot.utils.ValidatorUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 密码登录
 * @author Luyufan
 * @date 2024/1/11 09:17
 **/
@Slf4j
@Service("password" + IAuthStrategy.BASE_NAME)
@RequiredArgsConstructor
public class PasswordAuthStrategy implements IAuthStrategy {

    private final BaseSysUserDao baseSysUserDao;

    @Override
    public LoginVo login(String body, SysClient client) {
        LoginDto loginDto = JsonUtil.parseObject(body, LoginDto.class);
        ValidatorUtil.validate(loginDto);
        String username = loginDto.getUsername();
        SysUser sysUser = baseSysUserDao.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
        Assert.notNull(sysUser, "账号不存在");
        Assert.state(BCrypt.checkpw(loginDto.getPassword(), sysUser.getPassword()), "账号或密码不正确");
        Assert.equals(Constant.ONE, sysUser.getStatus(), "账号已被冻结");
        Long userId = sysUser.getUserId();
        LoginUser loginUser = new LoginUser().setUserId(userId)
                .setUsername(username).setRealName(sysUser.getRealName())
                .setNickName(sysUser.getNickName());
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        model.setExtra(AuthUtil.CLIENT_KEY, client.getClientCode());
        AuthUtil.login(loginUser, model);
        baseSysUserDao.update(null, Wrappers.<SysUser>lambdaUpdate()
                .set(SysUser::getLoginIp, ServerUtil.clientIp()).set(SysUser::getLoginTime, LocalDateTime.now())
                .eq(SysUser::getUserId, userId));
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        loginVo.setExpireIn(StpUtil.getTokenTimeout());
        loginVo.setClientCode(client.getClientCode());
        loginVo.setUserId(AuthUtil.getUserId());
        return loginVo;
    }
}
